package edu.gmu.atelier;

/**
 * Set of vectors with vector combination and scalar multiplication operations.
 * @author James H. Pope
 */
public class AffineVectorFactory implements VectorFactory
{
    public static final AffineVectorFactory INSTANCE = 
            new AffineVectorFactory();
    
    public AffineVectorFactory()
    {
        
    }
    
    //------------------------------------------------------------------------//
    // Factory methods
    //------------------------------------------------------------------------//
    
    public Vector makeVector( int n )
    {
//        if( n != 4 )
//        {
//            String s = "Invalid length, affine vector dim has to be 4, was "+n;
//            throw new IllegalArgumentException(s);
//        }
        
        double[] elems = new double[n];
        for (int i = 0; i < elems.length; i++)
        {
            elems[i] = 0.0;
        }
        //elems[AffineVector.W] = 1.0;
        return new AffineVector( elems );
    }
    
    public Matrix makeIdentity( int n )
    {
//        if( n != 4 )
//        {
//            String s = "Invalid length, affine vector dim has to be 4, was "+n;
//            throw new IllegalArgumentException(s);
//        }
        
        java.util.List<Vector> b = new java.util.ArrayList<Vector>();
        for (int c = 0; c < n; c++)
        {
            double[] elems = new double[n];
            elems[c] = 1.0;
            //elems[AffineVector.W] = 1.0;
            b.add(c, new AffineVector(elems) );
        }
        return new Matrix(b, this);
    }
    
    public Matrix makeIdentity( int m, int n )
    {
        java.util.List<Vector> b = new java.util.ArrayList<Vector>();
        int min = Math.min( m, n );
        for (int c = 0; c < min; c++)
        {
            double[] elems = new double[m];
            elems[c] = 1.0;
            b.add(c, new AffineVector(elems) );
        }
        return new Matrix(b, this);
    }
    
    /**
     * Makes a new matrix from data array in row-major order.
     * @param data
     * @return 
     */
    public Matrix makeMatrix(double[][] data)
    {
        java.util.List<Vector> b = new java.util.ArrayList<Vector>();
        for (int c = 0; c < data[0].length; c++)
        {
            double[] comps = new double[data.length];
            for (int r = 0; r < comps.length; r++)
            {
                comps[r] = data[r][c];
            }
            b.add(c, new AffineVector(comps) );
        }
        //return b;
        return new Matrix(b, INSTANCE);
    }

    /**
     * Makes a new vector from data.
     * @param data (column for vector)
     * @return 
     */
    public AffineVector makeVector(double[] data)
    {
        return new AffineVector(data);
    }
    
    /**
     * Makes a new mutable zero element.
     * @return 
     */
    public Element makeZero( )
    {
        return RealElement.ZERO.copy();
    }
    
    /**
     * Makes a new mutable one element.
     * @return 
     */
    public Element makeOne( )
    {
        return RealElement.ONE.copy();
    }
}
